using System.Collections.Generic;
using Gameplay.PVE.Utils;
using Yoozoo.Libs;
using Yoozoo.Managers;

namespace Gameplay.PVE.TurnBase
{
    public class ElementSystem : IClass
    {
        void IClass.OnReset()
        {
            Dispose();
        }

        private List<ElementBase> elementList = new List<ElementBase>();

        public void Init()
        {
            elementList.Clear();
        }

        public void OnDead()
        {
            for (int i = 0; i < elementList.Count; i++)
            {
                var element = elementList[i];
                element.IsFree = true;
            }
        }
        
        public void Update()
        {
            for (int i = 0; i < elementList.Count; i++)
            {
                var element = elementList[i];
                element.Update();
                if (element.IsFree)
                {
                    element.Free();
                    ClassManager.Free(element);
                    elementList.RemoveAt(i);
                    i--;
                }
            }
        }

        public void AddElement(BattleUnit target,BattleUnit source,TbsSkillElementConfig config)
        {
            var element = GetElementByType(config.element_type);
            if (element != null)
            {
                element.SetTarget(target,source);
                element.Parse(config);
                element.Execute();

                int combineType = element.config.combineType;
                if (combineType != 0)
                {
                    List<CombineElementRule> potentialRules = new List<CombineElementRule>();
                    List<List<int>> elementsNeeded = new List<List<int>>();
                    List<List<ElementBase>> elementsCombined = new List<List<ElementBase>>();
                    for (int i = 0; i < combineRules.Count; i++)
                    {
                        if (combineRules[i].elements.Contains(combineType))
                        {
                            potentialRules.Add(combineRules[i]);
                            var elements = new List<int>();
                            bool isSelfRemoved = false;
                            for (int j = 0; j < combineRules[i].elements.Count; j++)
                            {
                                int cType = combineRules[i].elements[j];
                                if (!isSelfRemoved && cType == combineType)
                                {
                                    isSelfRemoved = true;
                                }
                                else
                                {
                                    elements.Add(cType);
                                }
                            }
                            elementsNeeded.Add(elements);
                            elementsCombined.Add(new List<ElementBase>());
                        }
                    }

                    bool hasTriggered = false;
                    for (int i = 0; i < elementList.Count && !hasTriggered; i++)
                    {
                        var existElement = elementList[i];
                        if (!existElement.IsFree && existElement.config.combineType != 0)
                        {
                            int cType = existElement.config.combineType;
                            for (int j = 0; j < elementsNeeded.Count; j++)
                            {
                                var elements = elementsNeeded[j];
                                for (int k = 0; k < elements.Count; k++)
                                {
                                    if (elements[k] == cType)
                                    {
                                        elementsCombined[j].Add(existElement);
                                        elements.RemoveAt(k);
                                        break;
                                    }
                                }

                                if (elements.Count == 0)//说明触发了合并元素
                                {
                                    hasTriggered = true;
                                    //先删除元素
                                    for (int k = 0; k < elementsCombined[j].Count; k++)
                                    {
                                        elementsCombined[j][k].IsFree = true;
                                    }
                                    element.IsFree = true;
                                    var skillTemporaryArg = ClassManager.Get<TempSkillArg>();
                                    skillTemporaryArg.source = source;
                                    skillTemporaryArg.skillId = potentialRules[j].skillId;
                                    target.Transmit(ETransmitType.AddTemporarySkill,skillTemporaryArg);
                                    break;
                                }
                            }
                        }
                    }
                }
                
                elementList.Add(element);
            }
        }

        private struct CombineElementRule
        {
            public int skillId;
            public List<int> elements;
        }

        private List<CombineElementRule> combineRules = new List<CombineElementRule>
        {
            new CombineElementRule//冻伤
            {
                skillId = 10001,
                elements = new List<int>{2,3},
            },
            new CombineElementRule//爆炸
            {
                skillId = 10002,
                elements = new List<int>{4,5},
            }
        };

        private ElementBase GetElementByType(int type)
        {
            if (type == 1)
            {
                return ClassManager.Get<DamageElement>();
            }
            else if (type == 2)
            {
                return ClassManager.Get<ChangePropertyElement>();
            }
            else if (type == 3)
            {
                return ClassManager.Get<TriggerElement>();
            }
            else if (type == 4)
            {
                return ClassManager.Get<ControlElement>();
            }
            return null;
        }

        public void OnTransmit(ETransmitType type)
        {
            for (int i = 0; i < elementList.Count; i++)
            {
                if (elementList[i] is TriggerElement tri)
                {
                    int triggerElement = 0;
                    if (type == ETransmitType.RoundEnd)
                    {
                        triggerElement = tri.GetTriggerElement(2);
                    }
                    else if (type == ETransmitType.GetHurt)
                    {
                        triggerElement = tri.GetTriggerElement(5);
                    }
                    else if (type == ETransmitType.RoundStart)
                    {
                        triggerElement = tri.GetTriggerElement(1);
                    }

                    if (triggerElement != 0)
                    {
                        var config = PveUtils.GetTbsSkillElementConfig(triggerElement);
                        AddElement(tri.target,tri.source,config);
                        break;
                    }
                }
            }
            
            
            if (type == ETransmitType.RoundEnd)
            {
                for (int i = 0; i < elementList.Count; i++)
                {
                    var element = elementList[i];
                    if (element.endRound != 0 && element.endRound <= TurnBaseManager.Instance.GetRound())
                    {
                        element.Free();
                        ClassManager.Free(element);
                        elementList.RemoveAt(i);
                        i--;
                    }
                }
            }
        }
        
        public void Dispose()
        {
            elementList.Clear();
        }
    }
}